//
//  JCChatViewController.swift
//  JChat
//
//  Created by JIGUANG on 2017/2/28.
//  Copyright © 2017年 HXHG. All rights reserved.
//

import UIKit
import YHPhotoKit
import MobileCoreServices
import MTCategory
import YPNavigationBarTransition

extension JCChatViewController: MTTaskUserHeaderViewDelegate, MTSendRedpackWarningDelegate {
    func didClickCancel() {
        
    }
    
    func didClickSend(_ id: Int?) {
        if let partyTaskId = id {
//            MTRedpackTool.default.sendRedpack(self, self.conversation, partyTaskId) { flag in
//                if flag {
//                    self.partyInfoModel?.result?.type = .sendPack
//                    self.headerCountView.model = self.partyInfoModel
//                }
//            }
            MTCreateTaskTool.sendPartyTaskGift(provider: partyProvider, parameters: ["partyTaskId" : partyTaskId], complete: { (model) in
                if model?.code == 200 {
                    self.partyInfoModel?.result?.type = .sendPack
                    self.headerCountView.model = self.partyInfoModel
                }
            }) { (_) in
                
            }
        }
    }
    
    func didClickActionButton(sender: MTTaskUserHeaderView, userType: MTPartyGroupTaskUserType, actionStatus: MTPartyGroupTaskStatusType, canSign: Bool) {
        switch userType {
        case .ownner:
            switch actionStatus {
            case .wating, .started:
                sendRedpack(self.partyInfoModel?.result?.id)
                break
            default:
                
                break
            }
        case .sendPack:
            endParty()
            break
        default:
            switch userType {
            case .sign:
                break
            case .unsign:
                if canSign {
                    signAction(sender: sender)
                } else {
                    guard let tepGroup: JMSGGroup = conversation.target as? JMSGGroup else { return }
                    guard let gid = Int(tepGroup.gid) else { return }
                    let detailVC = MTPartyTaskDetailViewController()
                    detailVC.taskPushId = gid
                    self.navigationController?.pushViewController(detailVC, animated: true)
                }
                break
            default:
                break
            }
            break
        }
    }
    
    private func signAction(sender: MTTaskUserHeaderView) {
        guard let tepGroup: JMSGGroup = conversation.target as? JMSGGroup else { return }
        MTCreateTaskTool.partySign(provider: partyProvider, parameters: ["pushId" : tepGroup.gid], complete: { (model) in
            if model?.code == 200 {
                self.partyInfoModel?.result?.type = .sign
                self.headerCountView.model = self.partyInfoModel
            }
        }) { (_) in
            
        }
    }
    
    private func endParty() {
        guard let tepGroup: JMSGGroup = conversation.target as? JMSGGroup else { return }
        MTCreateTaskTool.endParty(provider: partyProvider, parameters: ["pushId" : tepGroup.gid], complete: { [weak self] (model) in
            guard let weakSelf = self else { return }
            if model?.code == 200 {
                DispatchQueue.main.async {
                    weakSelf.headerCountView.isHidden = true
                    weakSelf.chatView.snp.updateConstraints { (make) in
                        make.top.equalToSuperview().offset(0)
                    }
                }
            } else {
                
            }
        }) { (_) in
            DispatchQueue.main.async {
                MBProgressHUD_JChat.show(text: "活动暂未开始, 无法结束", view: self.view, 1)
            }
        }
    }
}

class JCChatViewController: BaseViewController {
    
    private lazy var partyProvider: MTProvider<MTCreateTaskAPI> = {
        let provider = MTProvider<MTCreateTaskAPI>()
        return provider
    }()
    
    open var conversation: JMSGConversation
    fileprivate var isGroup = false
    fileprivate var isPartyGroup = false
    fileprivate var partyInfoModel: MTTaskStatusInfoModel?
    fileprivate var warningView: MTSendRedpackWarning?
    
    private var imageMessages: [JMSGMessage] = []
//    private var currentImageMessage: JMSGMessage? = nil
    
    //MARK - life cycle
    public required init(conversation: JMSGConversation, _ isPartyGroup: Bool = false) {
        self.conversation = conversation
        self.isPartyGroup = isPartyGroup
        super.init()
        if let draft = JCDraft.getDraft(conversation) {
            self.draft = draft
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    required public init(rounterParams params: Dictionary<String, Any>?) {
        fatalError("init(rounterParams:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        _init()
    }
    
    override func loadView() {
        super.loadView()
        let frame = CGRect(x: 0, y: 0, width: self.view.width, height: self.view.height)
        chatView = JCChatView(frame: frame, chatViewLayout: chatViewLayout)
        chatView.delegate = self
        chatView.messageDelegate = self
        toolbar.translatesAutoresizingMaskIntoConstraints = false
        toolbar.delegate = self
        toolbar.text = draft
    }
    
    // MARK: - 聚会任务群相关嘻嘻
    private func queryPartyTaskInfo() {
         guard let tepGroup: JMSGGroup = conversation.target as? JMSGGroup else { return }
        MTCreateTaskTool.partyTaskGroupInfo(provider: partyProvider, parameters: ["pushId" : tepGroup.gid], complete: { [weak self] (model) in
            guard let weakSelf = self else { return }
            weakSelf.partyInfoModel = model
            if let m = model, m.code == 200, m.result?.status != .ended {
                weakSelf.headerCountView.model = model
                DispatchQueue.main.async {
                    weakSelf.headerCountView.isHidden = false
                    weakSelf.chatView.snp.updateConstraints { (make) in
                        make.top.equalToSuperview().offset(90 + StatusBarHeight + NavigationBarHeight)
                    }
                }
            } else if model?.code == 900 { /// 聚会任务群相关信息已经被删除了
                weakSelf.partyInfoModel?.isRevokePartyGroup = true
                weakSelf.headerCountView.isHidden = true
                weakSelf.chatView.snp.updateConstraints { (make) in
                    make.top.equalToSuperview().offset(0)
                }
            } else {
                weakSelf.headerCountView.isHidden = true
                weakSelf.chatView.snp.updateConstraints { (make) in
                    make.top.equalToSuperview().offset(0)
                }
            }
        }) { [weak self] (_) in
            guard let weakSelf = self else { return }
            weakSelf.headerCountView.isHidden = true
            weakSelf.chatView.snp.updateConstraints { (make) in
                make.top.equalToSuperview().offset(0)
            }
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.toolbar.isHidden = false
        _updateTitle()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: kUpdateConversation), object: nil, userInfo: nil)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardFrameChanged(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        if let group = conversation.target as? JMSGGroup {
            self.title = group.displayName()
        }
        navigationController?.interactivePopGestureRecognizer?.delegate = self
//        let attributes: [NSAttributedString.Key : Any] = [NSAttributedString.Key.font : PingFangSCMediumFont(16),
//                                                          NSAttributedString.Key.foregroundColor : UIColor(hex: 0xFFFFFF)]
//
//        navigationController?.navigationBar.titleTextAttributes = attributes
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        navigationController?.navigationBar.isTranslucent = true
        JCDraft.update(text: toolbar.text, conversation: conversation)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
        JMessage.remove(self, with: conversation)
    }
    
    private var draft: String?
    fileprivate lazy var toolbar: SAIInputBar = SAIInputBar(type: .default)
    fileprivate lazy var inputViews: [String: UIView] = [:]
    fileprivate weak var inputItem: SAIInputItem?
    var chatViewLayout: JCChatViewLayout = .init()
    var chatView: JCChatView!
    fileprivate lazy var reminds: [JCRemind] = []
    fileprivate lazy var documentInteractionController = UIDocumentInteractionController()
    
    lazy var headerCountView: MTTaskUserHeaderView = {
        let v = MTTaskUserHeaderView()
        v.backgroundColor = .red
        v.isHidden = true
        v.delegate = self
        return v
    }()
    
    fileprivate lazy var imagePicker: UIImagePickerController = {
        var picker = UIImagePickerController()
        picker.modalPresentationStyle = .fullScreen
        picker.sourceType = .camera
        picker.cameraCaptureMode = .photo
        picker.delegate = self
        return picker
    }()
    
    fileprivate lazy var videoPicker: UIImagePickerController = {
        var picker = UIImagePickerController()
        picker.modalPresentationStyle = .fullScreen
        picker.mediaTypes = [kUTTypeMovie as String]
        picker.sourceType = .camera
        picker.cameraCaptureMode = .video
        picker.videoMaximumDuration = 10
        picker.delegate = self
        return picker
    }()
    
    fileprivate lazy var _emoticonGroups: [JCCEmoticonGroup] = {
        var groups: [JCCEmoticonGroup] = []
        if let group = JCCEmoticonGroup(identifier: "com.apple.emoji") {
            groups.append(group)
        }
        if let group = JCCEmoticonGroup(identifier: "cn.jchat.guangguang") {
            groups.append(group)
        }
        return groups
    }()
    fileprivate lazy var _emoticonSendBtn: UIButton = {
        var button = UIButton()
        button.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        button.contentEdgeInsets = UIEdgeInsets.init(top: 0, left: 10 + 8, bottom: 0, right: 8)
        button.setTitle("发送", for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.setBackgroundImage(UIImage(color: UIColor.theme.main, size: CGSize(width: 60, height: 40)), for: .normal)
        button.setBackgroundImage(UIImage(color: .white, size: CGSize(width: 60, height: 40)), for: .disabled)
        button.addTarget(self, action: #selector(_sendHandler), for: .touchUpInside)
        return button
    }()
    fileprivate lazy var emoticonView: JCEmoticonInputView = {
        let emoticonView = JCEmoticonInputView(frame: CGRect(x: 0, y: 0, width: self.view.width, height: 275))
        emoticonView.delegate = self
        emoticonView.dataSource = self
        return emoticonView
    }()
    
    fileprivate lazy var toolboxView: SAIToolboxInputView = {
        var toolboxView = SAIToolboxInputView(frame: CGRect(x: 0, y: 0, width: self.view.width, height: 197))
        toolboxView.delegate = self
        toolboxView.dataSource = self
        return toolboxView
    }()
    fileprivate lazy var _toolboxItems: [SAIToolboxItem] = {
        
        if UserDefaults.AppValidate.isValidate.storedBool {
            return [
                        SAIToolboxItem("page:pic", "照片", UIImage.loadImage("chat_tool_pic")),
                        SAIToolboxItem("page:camera", "拍照", UIImage.loadImage("chat_tool_camera"))
                    ]
        }
        
        /// 客服会话屏蔽送礼和红包
        if conversation.ex.isSingle {
            let user: JMSGUser = conversation.target as! JMSGUser
            if user.username == UserCenter.default.customerUserName {
                return [
                            SAIToolboxItem("page:pic", "照片", UIImage.loadImage("chat_tool_pic")),
                            SAIToolboxItem("page:camera", "拍照", UIImage.loadImage("chat_tool_camera"))
                ]
            }
        }
        
        var toolItems: [SAIToolboxItem] = [
                    SAIToolboxItem("page:pic", "照片", UIImage.loadImage("chat_tool_pic")),
                    SAIToolboxItem("page:camera", "拍照", UIImage.loadImage("chat_tool_camera")),
                    SAIToolboxItem("page:redpack", "红包", UIImage.loadImage("icon_packet"))//,//,
//                    SAIToolboxItem("page:gift", "礼物", UIImage.loadImage("icon_gift_tool"))
                    //SAIToolboxItem("page:video_s", "小视频", UIImage.loadImage("chat_tool_video_short")),
        //            SAIToolboxItem("page:location", "位置", UIImage.loadImage("chat_tool_location")),
        //            SAIToolboxItem("page:businessCard", "名片", UIImage.loadImage("chat_tool_businessCard")),
                    ]
        return toolItems
    }()
    
    fileprivate var myAvator: UIImage?
    lazy var messages: [JCMessage] = []
    fileprivate let currentUser = JMSGUser.myInfo()
    fileprivate var messagePage = 0
    fileprivate var currentMessage: JCMessageType!
    fileprivate var maxTime = 0
    fileprivate var minTime = 0
    fileprivate var minIndex = 0
    fileprivate var jMessageCount = 0
    fileprivate var isFristLaunch = true
    fileprivate var recordingHub: JCRecordingView!
    /// 当前俱乐部id
    fileprivate var gid: String?
    /// 是否是俱乐部拥有者
    fileprivate var isClubOwner: Bool = false
    fileprivate lazy var recordHelper: JCRecordVoiceHelper = {
        let recordHelper = JCRecordVoiceHelper()
        recordHelper.delegate = self
        return recordHelper
    }()
    fileprivate lazy var provider: MTProvider<MiTuGiftApi> = {
        return MTProvider<MiTuGiftApi>(plugins: [])
    }()
    
    private func _init() {
        myAvator = UIImage.getMyAvator()
        isGroup = conversation.ex.isGroup
        
        /// 自己的群聊需要显示创建活动
        if isGroup {
            let tepGroup: JMSGGroup = conversation.target as! JMSGGroup
            let isOwner = tepGroup.owner == JMSGUser.myInfo().username
            if isOwner {
                isClubOwner = true
                gid = tepGroup.gid
                //_toolboxItems.append(SAIToolboxItem("page:activities", "活动", UIImage.loadImage("icon_huodong_big")))
                //toolboxView.reloadData()
            }
            /// 是俱乐部成员 / 俱乐部管理员, 可看见活动按钮
            if isOwner || tepGroup.memberInfo(withUsername: JMSGUser.myInfo().username, appkey: nil) != nil {
                _setupNavigation(true)
            } else {
                _setupNavigation(false)
            }
        } else {
            _setupNavigation(false)
        }
        
        //_updateTitle()
        view.backgroundColor = UIColor(hex: 0xF4F4F4)
        JMessage.add(self, with: conversation)
        // _setupNavigation()
        _loadMessage(messagePage)
        let tap = UITapGestureRecognizer(target: self, action: #selector(_tapView))
        tap.delegate = self
        chatView.addGestureRecognizer(tap)
        view.addSubview(chatView)
        view.addSubview(headerCountView)
        
        headerCountView.snp.makeConstraints { (make) in
            make.left.right.equalToSuperview()
            make.top.equalToSuperview().offset(StatusBarHeight + NavigationBarHeight)
            make.height.equalTo(90)
        }
        /// 单聊
        if isGroup == false {
            
            let user: JMSGUser = conversation.target as! JMSGUser
            let isFriend: Bool = user.isFriend
            if conversation.ex.isSingle, user.username != UserCenter.default.customerUserName {
                _toolboxItems.append(SAIToolboxItem("page:gift", "礼物", UIImage.loadImage("icon_gift_tool")))
                toolboxView.reloadData()
            }
//            if isFriend {
            chatView.snp.makeConstraints { (make) in
                make.left.right.top.equalToSuperview()
                make.bottom.equalToSuperview()
            }
        } else { /// 俱乐部聊天
            chatView.snp.makeConstraints { (make) in
                make.left.right.equalToSuperview()
                make.top.equalToSuperview().offset(0)
                make.bottom.equalToSuperview()
            }
        }
        
        
        
        _updateBadge()
        if self.isPartyGroup {
            queryPartyTaskInfo()
        }
        
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardFrameChanged(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(_removeAllMessage), name: NSNotification.Name(rawValue: kDeleteAllMessage), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(_reloadMessage), name: NSNotification.Name(rawValue: kReloadAllMessage), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(_updateFileMessage(_:)), name: NSNotification.Name(rawValue: kUpdateFileMessage), object: nil)
    }
    
    @objc func _updateFileMessage(_ notification: Notification) {
        let userInfo = notification.userInfo
        let msg = userInfo?[kUpdateFileMessage] as! JMSGMessage
        let msgId = msg.msgId
        let message = conversation.message(withMessageId: msgId)!
        let content = message.content as! JMSGFileContent
        let url = URL(fileURLWithPath: content.originMediaLocalPath ?? "")
        let data = try! Data(contentsOf: url)
        updateMediaMessage(message, data: data)
    }
    
    private func _updateTitle() {
        if let group = conversation.target as? JMSGGroup {
            title = group.displayName()
        } else {
            title = conversation.title
        }
        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.text.x1d1a1a, NSAttributedString.Key.font:PingFangSCSemiboldFont(16)]
    }


    @objc func _reloadMessage() {
        _removeAllMessage()
        messagePage = 0
        _loadMessage(messagePage)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
            self.chatView.scrollToLast(animated: false)
        }
    }
    
    @objc func _removeAllMessage() {
        jMessageCount = 0
        messages.removeAll()
        chatView.removeAll()
    }
    
    @objc func _tapView() {
        view.endEditing(true)
        toolbar.resignFirstResponder()
    }
    
    private func _setupNavigation(_ canseeActivities: Bool) {
//        let navButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
        let detailButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
        //detailButton.setTitle("详情", for: .normal)
        detailButton.setImage(UIImage(named: "chat-more"), for: .normal)
        detailButton.setTitleColor(.white, for: .normal)
        detailButton.titleLabel?.font = PingFangSCMediumFont(14)
        if isGroup {
//            if canseeActivities {
            detailButton.addTarget(self, action: #selector(_getGroupInfo), for: .touchUpInside)
            let item = UIBarButtonItem(customView: detailButton)
            navigationItem.rightBarButtonItems =  [item]
//            }
        } else {
            detailButton.addTarget(self, action: #selector(_getSingleInfo), for: .touchUpInside)
        }
        let item = UIBarButtonItem(customView: detailButton)
        navigationItem.rightBarButtonItems =  [item]
        navigationController?.interactivePopGestureRecognizer?.isEnabled = true
        navigationController?.interactivePopGestureRecognizer?.delegate = self
    }
    
//    @objc func _back() {
//        navigationController?.popViewController(animated: true)
//    }
    
    fileprivate func _loadMessage(_ page: Int) {
        printLog("\(page)")

        let messages = conversation.messageArrayFromNewest(withOffset: NSNumber(value: jMessageCount), limit: NSNumber(value: 17))
        if messages.count == 0 {
            return
        }
        var msgs: [JCMessage] = []
        for index in 0..<messages.count {
            let message = messages[index]
            let msg = _parseMessage(message)
            msgs.insert(msg, at: 0)
            /// 处理同意好友请求后的礼物状态
            if let dict: [String : Any] = msg.jmessage?.content?.extras as? [String : Any] {
                if let giftnotify: String = dict["messageType"] as? String, giftnotify == "giftnotify" {
                    if let model: MTUserNotifyModel = MTUserNotifyModel(JSON: dict), let lists = model.giftInfo {
                        for (_, v) in lists.enumerated() {
                            if let msgId = v.msgId, let status: Int = v.status, let s: MTGiftInfoStatus = MTGiftInfoStatus(rawValue: status) {
                                autoreleasepool {
                                    let giftInfo: MTGiftInfo = MTGiftInfo.create(msgId: "\(msgId)", status: s)
                                    MTGiftInfoDB.shareInstance.insertData(giftInfo)
                                }
                            }
                        }
                    }
                }
            }
            
            if isNeedInsertTimeLine(message.timestamp.intValue, content: msg.content) {
                let timeContent = JCMessageTimeLineContent(date: Date(timeIntervalSince1970: TimeInterval(message.timestamp.intValue / 1000)))
                let m = JCMessage(content: timeContent)
                m.options.showsTips = false
                msgs.insert(m, at: 0)
            }
        }
        if page != 0 {
            minIndex = minIndex + msgs.count
            chatView.insert(contentsOf: msgs, at: 0)
        } else {
            minIndex = msgs.count - 1
            chatView.append(contentsOf: msgs)
        }
        self.messages.insert(contentsOf: msgs, at: 0)
    }
    
    private func isNeedInsertTimeLine(_ time: Int, content: JCMessageContentType) -> Bool {
        /// 领取礼物自定义消息不需要显示发送时间
        if content is JCMessagePullGiftNotiyContent {
            return false
        }
        /// 同意好友请求后, 自动领取所有礼物, 后台发出的通知改变礼物状态的消息, 不需要显示发送时间
        if content is JCMessageGiftNotiyContent {
            return false
        }
        /// 聚会任务群, 聚会任务结束, 后台发出的通知前台界面改变的通知消息, 不需要显示发送时间
        if content is JCMessageEndPartyContent {
            return false
        }
        
        if maxTime == 0 || minTime == 0 {
            maxTime = time
            minTime = time
            return true
        }
        if (time - maxTime) >= 5 * 60000 {
            maxTime = time
            return true
        }
        if (minTime - time) >= 5 * 60000 {
            minTime = time
            return true
        }
        return false
    }
    
    // MARK: - parse message
    fileprivate func _parseMessage(_ message: JMSGMessage, _ isNewMessage: Bool = true) -> JCMessage {
        if isNewMessage {
            jMessageCount += 1
        }
        return message.parseMessage(self, { [weak self] (message, data) in
            self?.updateMediaMessage(message, data: data)
        })
    }

    // MARK: - send message
    func send(_ message: JCMessage, _ jmessage: JMSGMessage) {
        let msg = _parseMessage(jmessage)
        if isNeedInsertTimeLine(jmessage.timestamp.intValue, content: msg.content) {
            let timeContent = JCMessageTimeLineContent(date: Date(timeIntervalSince1970: TimeInterval(jmessage.timestamp.intValue / 1000)))
            let m = JCMessage(content: timeContent)
            m.options.showsTips = false
            messages.append(m)
            chatView.append(m)
        }
        message.msgId = jmessage.msgId
        message.name = currentUser.displayName()
        message.senderAvator = myAvator
        message.sender = currentUser
        message.options.alignment = .right
        message.options.state = .sending
        if let group = conversation.target as? JMSGGroup {
            message.targetType = .group
            message.unreadCount = group.memberArray().count - 1
        } else {
            message.targetType = .single
            message.unreadCount = 1
        }
        chatView.append(message)
        messages.append(message)
        chatView.scrollToLast(animated: false)
        /// 附加自定义信息
        let conversationType = self.conversation.conversationType
        if conversationType == .single {
            jmessage.content?.addStringExtra(JMSGUser.myInfo().username, forKey: "userName")
        } else if conversationType == .group {
            if let group = conversation.target as? JMSGGroup {
                jmessage.content?.addStringExtra(group.gid, forKey: "gid")
            }
        }
        
        conversation.send(jmessage, optionalContent: JMSGOptionalContent.ex.default)
    }

    func send(forText text: NSAttributedString) {
        let message = JCMessage(content: JCMessageTextContent(attributedText: text))
        let content = JMSGTextContent(text: text.string)
        let msg = JMSGMessage.ex.createMessage(conversation, content, reminds)
        reminds.removeAll()
        send(message, msg)
    }
    
    func send(forLargeEmoticon emoticon: JCCEmoticonLarge) {
        guard let image = emoticon.contents as? UIImage else {
            return
        }
        let messageContent = JCMessageImageContent()
        messageContent.image = image
        messageContent.delegate = self
        messageContent.isLargeEmoticon = true
        let message = JCMessage(content: messageContent)
        
        let content = JMSGImageContent(imageData: image.pngData()!)
        let msg = JMSGMessage.ex.createMessage(conversation, content!, nil)
        msg.ex.isLargeEmoticon = true
        message.options.showsTips = true
        send(message, msg)
    }
    
    func send(forImage image: UIImage) {
        let data = image.jpegData(compressionQuality: 1.0)!
        if let content = JMSGImageContent(imageData: data) {
            let message = JMSGMessage.ex.createMessage(conversation, content, nil)
            let imageContent = JCMessageImageContent()
            imageContent.delegate = self
            imageContent.image = image
            content.uploadHandler = {  (percent:Float, msgId:(String?)) -> Void in
                imageContent.upload?(percent)
            }
            let msg = JCMessage(content: imageContent)
            send(msg, message)
        }
    }
    
    func send(voiceData: Data, duration: Double) {
        let voiceContent = JCMessageVoiceContent()
        voiceContent.data = voiceData
        voiceContent.duration = duration
        voiceContent.delegate = self
        let content = JMSGVoiceContent(voiceData: voiceData, voiceDuration: NSNumber(value: duration))
        let message = JMSGMessage.ex.createMessage(conversation, content, nil)
        
        let msg = JCMessage(content: voiceContent)
        send(msg, message)
    }
    func send(videoData: Data, thumbData: Data, duration: Double,format: String)  {
        let time = NSNumber(value: duration)
        let content = JMSGVideoContent(videoData: videoData, thumbData: thumbData, duration: time)
        content.format = format
        let message = JMSGMessage.ex.createMessage(conversation, content, nil)
        
        let videoContent = JCMessageVideoContent()
        videoContent.videoContent = content
        videoContent.data = videoData
        videoContent.image = UIImage(data: thumbData)
        videoContent.delegate = self
        
        let msg = JCMessage(content: videoContent)
        send(msg, message);
    }
    func send(fileData: Data, fileName: String) {
        let videoContent = JCMessageVideoContent()
        videoContent.data = fileData
        videoContent.delegate = self

        let content = JMSGFileContent(fileData: fileData, fileName: fileName)
        let message = JMSGMessage.ex.createMessage(conversation, content, nil)
        let msg = JCMessage(content: videoContent)
        send(msg, message)
    }
    
    func send(address: String, lon: NSNumber, lat: NSNumber) {
        let locationContent = JCMessageLocationContent()
        locationContent.address = address
        locationContent.lat = lat.doubleValue
        locationContent.lon = lon.doubleValue
        locationContent.delegate = self
        
        let content = JMSGLocationContent(latitude: lat, longitude: lon, scale: NSNumber(value: 1), address: address)
        let message = JMSGMessage.ex.createMessage(conversation, content, nil)
        let msg = JCMessage(content: locationContent)
        send(msg, message)
    }
    
    func sendRedpack(_ id: Int? = nil) {
        if self.partyInfoModel?.isRevokePartyGroup == true {
            MBProgressHUD_JChat.show(text: "聚会任务群已解散", view: self.view, 1)
            return
        }
        if let partyTaskId = id {
            let warning: MTSendRedpackWarning = MTSendRedpackWarning(frame: CGRect(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight))
            self.warningView = warning
            self.warningView!.partyTaskId = partyTaskId
            self.warningView!.delegate = self
            UIApplication.shared.keyWindow?.addSubview(self.warningView!)
            return
        }
        MTRedpackTool.default.sendRedpack(self, self.conversation) { _ in
            
        }
    }
    // MARK: - 创建俱乐部活动
    func createClubActivities() {
        
        /// 只有俱乐部拥有者可以创建活动
        if isGroup {
            if isClubOwner {
                let createClubVC = MTClubActiviteDetailViewController(group: self.conversation.target as! JMSGGroup, isCreateContet: true)
                self.navigationController?.pushViewController(createClubVC, animated: true)
            } else {
                let g = self.conversation.target as! JMSGGroup
                self.navigationController?.pushViewController(MTClubActivitiesViewController(clubId: g.gid), animated: true)
            }
        }
    }
    
    @objc func keyboardFrameChanged(_ notification: Notification) {
        let dic = NSDictionary(dictionary: (notification as NSNotification).userInfo!)
        let keyboardValue = dic.object(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue
        let bottomDistance = UIScreen.main.bounds.size.height - keyboardValue.cgRectValue.origin.y
//        let duration = Double(dic.object(forKey: UIResponder.keyboardAnimationDurationUserInfoKey) as! NSNumber)
        let duration = Double(truncating: dic.object(forKey: UIResponder.keyboardAnimationDurationUserInfoKey) as! NSNumber)
        
        UIView.animate(withDuration: duration, animations: {
        }) { (finish) in
            if (bottomDistance == 0 || bottomDistance == self.toolbar.height) && !self.isFristLaunch {
                return
            }
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
                self.chatView.scrollToLast(animated: false)
            }
            self.isFristLaunch = false
        }
    }
    
    @objc func _sendHandler() {
        let text = toolbar.attributedText
        if text != nil && (text?.length)! > 0 {
            send(forText: text!)
            toolbar.attributedText = nil
        }
    }
    
    @objc func _getSingleInfo() {
        //let vc = JCSingleSettingViewController()
        let vc = MTChatSingleDetailViewController()
        vc.user = conversation.target as? JMSGUser
        vc.conversation = conversation
        navigationController?.pushViewController(vc, animated: true)
    }
    
    @objc func _getGroupInfo() {
        let tepGroup: JMSGGroup = conversation.target as! JMSGGroup
        /// 如果是聚会任务群
        if isPartyGroup {
            /// 如果聚会人去群已解散 - 给予提示
            if self.partyInfoModel?.isRevokePartyGroup == true {
                MBProgressHUD_JChat.show(text: "聚会任务群已解散", view: self.view, 1)
                return
            }
            if let partyId = self.partyInfoModel?.result?.id {
                let detailVC = MTPartyTaskDetailViewController(partyTaskId: partyId)
                self.navigationController?.pushViewController(detailVC, animated: true)
                return
            }
            guard let gid = Int(tepGroup.gid) else { return }
            let detailVC = MTPartyTaskDetailViewController()
            detailVC.taskPushId = gid
            self.navigationController?.pushViewController(detailVC, animated: true)
            return
        } else {
            if isClubOwner {
                let detailVc = MTCreateClubViewController(isEditMode: true, clubId: tepGroup.gid) { (flag) in
                    
                }
                detailVc.group = tepGroup
                detailVc.conversation = self.conversation
                navigationController?.pushViewController(detailVc, animated: true)
                return
            }
            let detailVc = MTNewClubDetailViewController()
            detailVc.group = tepGroup
            detailVc.comformChat = true
            navigationController?.pushViewController(detailVc, animated: true)
        }
    }
    // MARK: - 俱乐部所有活动
    @objc func clubActivities() {
        let group = conversation.target as! JMSGGroup
        let vc = MTClubActivitiesViewController(clubId: group.gid)
        //vc.group = group
        navigationController?.pushViewController(vc, animated: true)
    }
}

//MARK: - JMSGMessage Delegate
extension JCChatViewController: JMessageDelegate {
    
    fileprivate func updateMediaMessage(_ message: JMSGMessage, data: Data?) {
        DispatchQueue.main.async {
            if let index = self.messages.index(message) {
                let msg = self.messages[index]
                switch(message.contentType) {
                case .file:
                    printLog("update file message")
                    if message.ex.isShortVideo {
                        let videoContent = msg.content as! JCMessageVideoContent
                        videoContent.data = data
                        videoContent.delegate = self
                        msg.content = videoContent
                    } else {
                        let fileContent = msg.content as! JCMessageFileContent
                        fileContent.data = data
                        fileContent.delegate = self
                        msg.content = fileContent
                    }
                case .video:
                    printLog("updare video message")
                    let videoContent = msg.content as! JCMessageVideoContent
                    videoContent.image = UIImage(data: data!)
                    videoContent.delegate = self
                    msg.content = videoContent
                case .image:
                    let imageContent = msg.content as! JCMessageImageContent
                    let image = UIImage(data: data!)
                    imageContent.image = image
                    msg.content = imageContent
                default: break
                }
                msg.updateSizeIfNeeded = true
                self.chatView.update(msg, at: index)
                msg.updateSizeIfNeeded = false
//                self.chatView.update(msg, at: index)
            }
        }
    }
    
    func _updateBadge() {
        JMSGConversation.allConversations { (result, error) in
            guard let conversations = result as? [JMSGConversation] else {
                return
            }
            let count = conversations.unreadCount
            if count == 0 {
//                self.leftButton.setTitle("会话", for: .normal)
            } else {
//                self.leftButton.setTitle("会话(\(count))", for: .normal)
            }
        }
    }
    /// 在服务器下发消息回调的时候 - 本地存储礼物状态信息
    func onReceive(_ message: JMSGMessage!, error: Error!) {
        if error != nil {
            return
        }
        
        let message = _parseMessage(message)
        /// 是任务结束时候发送的消息 - 通知用户的任务条消失
        if let dict: [String : Any] = message.jmessage?.content?.extras as? [String : Any] {
            if let partytask: String = dict["messageType"] as? String, partytask == "partytask" {
                if let status: Int = dict["status"] as? Int, status == 3 {
                    DispatchQueue.main.async {
                        self.headerCountView.removeFromSuperview()
                        self.chatView.snp.updateConstraints { (make) in
                            make.top.equalToSuperview().offset(0)
                        }
                    }
                }
            }
        }
        
        if messages.contains(where: { (m) -> Bool in
            return m.msgId == message.msgId
        }) {
            let indexs = chatView.indexPathsForVisibleItems
            for index in indexs {
                var m = messages[index.row]
                if !m.msgId.isEmpty {
                    if let jmsg = conversation.message(withMessageId: m.msgId) {
                        m = _parseMessage(jmsg, false)
                        chatView.update(m, at: index.row)
                    }
                }
            }
            return
        }
        
        /// 礼物消息状态本地缓存 - 此处处理为礼物发送人本地状态缓存
        if let dict: [String : Any] = message.jmessage?.content?.extras as? [String : Any] {
            if let partytask: String = dict["messageType"] as? String, partytask == "pullGift" {
                if let msgId = dict["msgId"] as? String, let status: Int = dict["status"] as? Int {
                    let giftInfo: MTGiftInfo = MTGiftInfo.create(msgId: msgId, status: MTGiftInfoStatus(rawValue: status)!)
                    MTGiftInfoDB.shareInstance.insertData(giftInfo)
                    /// 找到对应id的礼物消息刷新
                    if self.messages.contains(where: { (m) -> Bool in
                        return m.jmessage?.serverMessageId == msgId
                    }) {
                        let indexs = chatView.indexPathsForVisibleItems
                        for index in indexs {
                            var m = messages[index.row]
                            if !m.msgId.isEmpty {
                                m = _parseMessage(conversation.message(withMessageId: m.msgId)!, false)
                                chatView.update(m, at: index.row)
//                                DispatchQueue.main.async {
//                                    if status == 1 {
//                                        MBProgressHUD_JChat.show(text: "对方已成功领取你的礼物", view: self.view, 1)
//                                    }
//                                }
                            }
                        }
                    }
                }
            }
        }
        
        messages.append(message)
        chatView.append(message)
        updateUnread([message])
        conversation.clearUnreadCount()
        if !chatView.isRoll {
            //chatView.scrollToLast(animated: true)
        }
        _updateBadge()
    }
    
    func onSendMessageResponse(_ message: JMSGMessage!, error: Error!) {
        if let error = error as NSError? {
            if error.code == 803009 {
                MBProgressHUD_JChat.show(text: "发送失败，消息中包含敏感词", view: view, 2.0)
            }
            if error.code == 803005 {
                MBProgressHUD_JChat.show(text: !self.isPartyGroup ? "您已不是俱乐部成员" : "您已取消参加聚会任务", view: view, 2.0)
            }
        }
        if let index = messages.index(message) {
            let msg = messages[index]
            msg.options.state = message.ex.state
            chatView.update(msg, at: index)
            jMessageCount += 1
        }
    }
    
    func onReceive(_ retractEvent: JMSGMessageRetractEvent!) {
        if let index = messages.index(retractEvent.retractMessage) {
            let msg = _parseMessage(retractEvent.retractMessage, false)
            messages[index] = msg
            chatView.update(msg, at: index)
        }
    }
    
    func onSyncOfflineMessageConversation(_ conversation: JMSGConversation!, offlineMessages: [JMSGMessage]!) {
        let msgs = offlineMessages.sorted(by: { (m1, m2) -> Bool in
            return m1.timestamp.intValue < m2.timestamp.intValue
        })
        for item in msgs {
            let message = _parseMessage(item)
            messages.append(message)
            chatView.append(message)
            updateUnread([message])
            conversation.clearUnreadCount()
            if !chatView.isRoll {
                chatView.scrollToLast(animated: true)
            }
        }
        _updateBadge()
    }
    
    func onReceive(_ receiptEvent: JMSGMessageReceiptStatusChangeEvent!) {
        for message in receiptEvent.messages! {
            if let index = messages.index(message) {
                let msg = messages[index]
                msg.unreadCount = message.getUnreadCount()
                chatView.update(msg, at: index)
            }
        }
    }
}

// MARK: - JCEmoticonInputViewDataSource & JCEmoticonInputViewDelegate
extension JCChatViewController: JCEmoticonInputViewDataSource, JCEmoticonInputViewDelegate {
    
    open func numberOfEmotionGroups(in emoticon: JCEmoticonInputView) -> Int {
        return _emoticonGroups.count
    }

    open func emoticon(_ emoticon: JCEmoticonInputView, emotionGroupForItemAt index: Int) -> JCEmoticonGroup {
        return _emoticonGroups[index]
    }

    open func emoticon(_ emoticon: JCEmoticonInputView, numberOfRowsForGroupAt index: Int) -> Int {
        return _emoticonGroups[index].rows
    }

    open func emoticon(_ emoticon: JCEmoticonInputView, numberOfColumnsForGroupAt index: Int) -> Int {
        return _emoticonGroups[index].columns
    }

    open func emoticon(_ emoticon: JCEmoticonInputView, moreViewForGroupAt index: Int) -> UIView? {
        if _emoticonGroups[index].type.isSmall {
            return _emoticonSendBtn
        } else {
            return nil
        }
    }

    open func emoticon(_ emoticon: JCEmoticonInputView, insetForGroupAt index: Int) -> UIEdgeInsets {
        return UIEdgeInsets.init(top: 12, left: 10, bottom: 12 + 24, right: 10)
    }

    open func emoticon(_ emoticon: JCEmoticonInputView, didSelectFor item: JCEmoticon) {
        if item.isBackspace {
            toolbar.deleteBackward()
            return
        }
        if let emoticon = item as? JCCEmoticonLarge {
            send(forLargeEmoticon: emoticon)
            return
        }
        if let code = item.contents as? String {
            return toolbar.insertText(code)
        }
        if let image = item.contents as? UIImage {
            let d = toolbar.font?.descender ?? 0
            let h = toolbar.font?.lineHeight ?? 0
            let attachment = NSTextAttachment()
            attachment.image = image
            attachment.bounds = CGRect(x: 0, y: d, width: h, height: h)
            toolbar.insertAttributedText(NSAttributedString(attachment: attachment))
            return
        }
    }
}

// MARK: - SAIToolboxInputViewDataSource & SAIToolboxInputViewDelegate
extension JCChatViewController: SAIToolboxInputViewDataSource, SAIToolboxInputViewDelegate {
    
    open func toolboxInputViewContentSize(_ inputView: UIView) -> CGSize {
        return CGSize(width: view.frame.width, height: 138)
    }
    
    open func numberOfToolboxItems(in toolbox: SAIToolboxInputView) -> Int {
        return _toolboxItems.count
    }
    open func toolbox(_ toolbox: SAIToolboxInputView, toolboxItemForItemAt index: Int) -> SAIToolboxItem {
        return _toolboxItems[index]
    }
    /// 工具条有几行
    open func toolbox(_ toolbox: SAIToolboxInputView, numberOfRowsForSectionAt index: Int) -> Int {
        return 1
    }
    open func toolbox(_ toolbox: SAIToolboxInputView, numberOfColumnsForSectionAt index: Int) -> Int {
        return 4
    }
    open func toolbox(_ toolbox: SAIToolboxInputView, insetForSectionAt index: Int) -> UIEdgeInsets {
        return UIEdgeInsets.init(top: 12, left: 10, bottom: 12, right: 10)
    }
    open func toolbox(_ toolbox: SAIToolboxInputView, shouldSelectFor item: SAIToolboxItem) -> Bool {
        return true
    }
    private func _pushToSelectPhotos() {
        let vc = YHPhotoPickerViewController()
        vc.modalPresentationStyle = .fullScreen
        vc.modalTransitionStyle = .crossDissolve
        vc.maxPhotosCount = 9;
        vc.pickerDelegate = self
        present(vc, animated: true)
    }
    open func toolbox(_ toolbox: SAIToolboxInputView, didSelectFor item: SAIToolboxItem) {
        toolbar.resignFirstResponder()
        switch item.identifier {
        case "page:pic":
            if PHPhotoLibrary.authorizationStatus() != .authorized {
                PHPhotoLibrary.requestAuthorization({ (status) in
                    DispatchQueue.main.sync {
                        if status != .authorized {
                            JCAlertView.bulid().setTitle("无权限访问照片").setMessage("请在设备的设置-觅颜Me中允许访问照片。").setDelegate(self).addCancelButton("好的").addButton("去设置").setTag(10001).show()
                        } else {
                            self._pushToSelectPhotos()
                        }
                    }
                })
            } else {
                _pushToSelectPhotos()
            }
        case "page:camera":
            present(imagePicker, animated: true, completion: nil)
        case "page:video_s":
            present(videoPicker, animated: true, completion: nil)
//        case "page:location":
//            let vc = JCAddMapViewController()
//            vc.addressBlock = { (dict: Dictionary?) in
//                if dict != nil {
//                    let lon = Float(dict?["lon"] as! String)
//                    let lat = Float(dict?["lat"] as! String)
//                    let address = dict?["address"] as! String
//                    self.send(address: address, lon: NSNumber(value: lon!), lat: NSNumber(value: lat!))
//                }
//            }
//            navigationController?.pushViewController(vc, animated: true)
        case "page:businessCard":
            let vc = FriendsBusinessCardViewController()
            vc.conversation = conversation
            let nav = BaseNavController(rootViewController: vc)
            present(nav, animated: true, completion: {
                self.toolbar.isHidden = true
            })
        case "page:redpack":
            debugPrint("红包")
            self.sendRedpack()
//        case "page:activities":
//            self.createClubActivities()
        case "page:gift":
            self.sendGift()
            break
        default:
            break
        }
    }
    
//    open override func present(_ viewControllerToPresent: BaseViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
//        super.present(viewControllerToPresent, animated: flag, completion: completion)
//    }
}

// MARK: - UIImagePickerControllerDelegate & YHPhotoPickerViewControllerDelegate
extension JCChatViewController: YHPhotoPickerViewControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    func selectedPhotoBeyondLimit(_ count: Int32, currentView view: UIView!) {
        MBProgressHUD_JChat.show(text: "最多选择\(count)张图片", view: nil)
    }
    
    func yhPhotoPickerViewController(_ PhotoPickerViewController: YHSelectPhotoViewController!, selectedPhotos photos: [Any]!) {
        for item in photos {
            guard let photo = item as? UIImage else {
                return
            }
            DispatchQueue.main.async {
                self.send(forImage: photo)
            }
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // Local variable inserted by Swift 4.2 migrator.
        let infoE = convertFromUIImagePickerControllerInfoKeyDictionary(info)
        
        picker.dismiss(animated: true, completion: nil)
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            send(forImage: image.fixOrientation())
        } else {
            loadImageFromPicker(info: info)
        }
        
        let videoUrl = infoE[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.mediaURL)] as! URL?
        if videoUrl != nil {
            let format = "mov" //系统拍的是 mov 格式
            let videoData = try! Data(contentsOf: videoUrl!)
            let thumb = self.videoFirstFrame(videoUrl!, size: CGSize(width: JC_VIDEO_MSG_IMAGE_WIDTH, height: JC_VIDEO_MSG_IMAGE_HEIGHT));
            let thumbData = thumb.pngData()
            let avUrl = AVURLAsset(url: videoUrl!)
            let time = avUrl.duration
            let seconds = ceil(Double(time.value)/Double(time.timescale))
            self.send(videoData: videoData, thumbData: thumbData!, duration: seconds, format: format)
            
            /* 可选择转为 MP4 再发
             conversionVideoFormat(videoUrl!) { (paraUrl) in
             if paraUrl != nil {
             //send  video message
             }
             }*/
        }
    }
    
    private func loadImageFromPicker(info: [UIImagePickerController.InfoKey : Any]) {
        guard let referenceURL = info[UIImagePickerController.InfoKey.phAsset] as? URL else {
            return
        }
        let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
        guard let phAsset = fetchResult.firstObject else {
            return
        }
        // size doesn't matter, because resizeMode = .none
        let size = CGSize(width: 32, height: 32)
        let options = PHImageRequestOptions()
        options.version = .original
        options.deliveryMode = .highQualityFormat
        options.resizeMode = .none
        options.isNetworkAccessAllowed = true
        PHImageManager.default().requestImage(for: phAsset, targetSize: size, contentMode: .aspectFit, options: options) { [weak self] (image, info) in
            if let weakSelf = self, let image = image {
                DispatchQueue.main.async {
                    weakSelf.send(forImage: image.fixOrientation())
                }
            }
        }
    }
    
    // 视频转 MP4 格式
    func conversionVideoFormat(_ inputUrl: URL,callback: @escaping (_ para: URL?) -> Void){
        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd-HH:mm:ss"
        let strDate = formatter.string(from: date) as String
        
        let path = "\(NSHomeDirectory())/Documents/output-\(strDate).mp4"
        let outputUrl: URL = URL(fileURLWithPath: path)
        
        let avAsset = AVURLAsset(url: inputUrl)
        let exportSeesion = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetMediumQuality)
        exportSeesion?.outputURL = outputUrl
        exportSeesion?.outputFileType = AVFileType.mp4
        exportSeesion?.exportAsynchronously(completionHandler: {
            switch exportSeesion?.status {
            case AVAssetExportSession.Status.unknown?:
                break;
            case AVAssetExportSession.Status.cancelled?:
                callback(nil)
                break;
            case AVAssetExportSession.Status.waiting?:
                break;
            case AVAssetExportSession.Status.exporting?:
                break;
            case AVAssetExportSession.Status.completed?:
                callback(outputUrl)
                break;
            case AVAssetExportSession.Status.failed?:
                callback(nil)
                break;
            default:
                callback(nil)
                break
            }
        })
    }
    // 获取视频第一帧
    func videoFirstFrame(_ videoUrl: URL, size: CGSize) -> UIImage {
        let opts = [AVURLAssetPreferPreciseDurationAndTimingKey:false]
        let urlAsset = AVURLAsset(url: videoUrl, options: opts)
        let generator = AVAssetImageGenerator(asset: urlAsset)
        generator.appliesPreferredTrackTransform = true
        generator.maximumSize = CGSize(width: size.width, height: size.height)
        //let error: Error
        do {
            let img = try generator.copyCGImage(at: CMTimeMake(value: 0, timescale: 10), actualTime: nil) as CGImage
            let image = UIImage(cgImage: img)
            return image
        } catch let error as NSError {
            debugPrint("\(error)")
            return UIImage.createImage(color: .gray, size: CGSize(width: JC_VIDEO_MSG_IMAGE_WIDTH, height: JC_VIDEO_MSG_IMAGE_HEIGHT))!
        }
    }
}

// MARK: - JCMessageDelegate
extension JCChatViewController: JCMessageDelegate {

    func message(message: JCMessageType, videoData data: Data?) {
        if let data = data {
            JCVideoManager.playVideo(data: data, currentViewController: self)
        }
    }

    func message(message: JCMessageType, location address: String?, lat: Double, lon: Double) {
//        let vc = JCAddMapViewController()
//        vc.isOnlyShowMap = true
//        vc.lat = lat
//        vc.lon = lon
//        navigationController?.pushViewController(vc, animated: true)
    }
    
    func message(message: JCMessageType, image: UIImage?) {
//        let browserImageVC = JCImageBrowserViewController()
//        browserImageVC.messages = messages
//        browserImageVC.conversation = conversation
//        browserImageVC.currentMessage = message
        
        
//        let browserImageVC = MTImageBrowserViewController()
//        browserImageVC.messages = messages
//        browserImageVC.conversation = conversation
//        browserImageVC.currentMessage = message
//
//        let nav = BaseNavController(rootViewController: browserImageVC)
//        nav.modalPresentationStyle = .fullScreen
//        present(nav, animated: true) {
//            self.toolbar.isHidden = true
//        }
        imageMessages.removeAll()
        
        imageMessages = getImageMessages(messages)
        if imageMessages.count > 0 {
            var currentIndex = 0
            if let index = imageMessages.index(where: { (m) -> Bool in
                m.msgId == message.msgId
            }) {
                currentIndex = index
            }
            
            let broswer = AAPhotoBrowser.init(with: self)
            broswer.selectedIndex = currentIndex
            broswer.presentDuration = 0.3
            broswer.dissmissDuration = 0.3
            present(broswer, animated: true) {
//                self.toolbar.isHidden = true
            }
        }
    }
    
    func getImageMessages(_ messages: [JCMessageType]) -> [JMSGMessage] {
        var imageMessages: [JMSGMessage] = []
        for message in messages {
            var msg: JMSGMessage?
            if message.targetType == .chatRoom {
                msg = message.jmessage
            }else{
                msg = conversation.message(withMessageId: message.msgId)
            }
            if msg != nil {
                if msg?.contentType == .image {
                    imageMessages.append(msg!)
                }
            }
        }
        return imageMessages
    }
    
    func message(message: JCMessageType, fileData data: Data?, fileName: String?, fileType: String?) {
        if data == nil {
            let vc = JCFileDownloadViewController()
            vc.title = fileName
            let msg = conversation.message(withMessageId: message.msgId)
            vc.fileSize = msg?.ex.fileSize
            vc.message = msg
            navigationController?.pushViewController(vc, animated: true)
        } else {
            guard let fileType = fileType else {
                return
            }
            let msg = conversation.message(withMessageId: message.msgId)!
            let content = msg.content as! JMSGFileContent
            switch fileType.fileFormat() {
            case .document:
                let vc = JCDocumentViewController()
                vc.title = fileName
                vc.fileData = data
                vc.filePath = content.originMediaLocalPath
                vc.fileType = fileType
                navigationController?.pushViewController(vc, animated: true)
            case .video, .voice:
                let url = URL(fileURLWithPath: content.originMediaLocalPath ?? "")
                try! JCVideoManager.playVideo(data: Data(contentsOf: url), fileType, currentViewController: self)
            case .photo:
                let browserImageVC = JCImageBrowserViewController()
                let image = UIImage(contentsOfFile: content.originMediaLocalPath ?? "")
                browserImageVC.imageArr = [image!]
                browserImageVC.imgCurrentIndex = 0
//                present(browserImageVC, animated: true) {
//                    self.toolbar.isHidden = true
//                }
            default:
                let url = URL(fileURLWithPath: content.originMediaLocalPath ?? "")
                documentInteractionController.url = url
                documentInteractionController.presentOptionsMenu(from: .zero, in: self.view, animated: true)
            }
        }
    }

    func message(message: JCMessageType, user: JMSGUser?, businessCardName: String, businessCardAppKey: String) {
        if let user = user {
            let vc = JCUserInfoViewController()
            vc.user = user
            navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    func clickTips(message: JCMessageType) {
        currentMessage = message
        let alertView = UIAlertView(title: "重新发送", message: "是否重新发送该消息？", delegate: self, cancelButtonTitle: "取消", otherButtonTitles: "发送")
        alertView.show()
    }
    
    func tapAvatarView(message: JCMessageType) {
        toolbar.resignFirstResponder()
//        if message.options.alignment == .right {
//            //navigationController?.pushViewController(JCMyInfoViewController(), animated: true)
//
//        } else {
//
//            //let vc = JCUserInfoViewController()
//            //vc.user = message.sender
//            //navigationController?.pushViewController(vc, animated: true)
//        }
//
        let c = MineViewController(username: message.sender?.username)
        navigationController?.pushViewController(c, animated: true)
    }

    func longTapAvatarView(message: JCMessageType) {
        if !isGroup || message.options.alignment == .right {
            return
        }
        toolbar.becomeFirstResponder()
        if let user = message.sender {
            toolbar.text.append("@")
            handleAt(toolbar, NSMakeRange(toolbar.text.length - 1, 0), user, false, user.displayName().length)
        }
    }

    func tapUnreadTips(message: JCMessageType) {
        let vc = UnreadListViewController()
        let msg = conversation.message(withMessageId: message.msgId)
        vc.message = msg
        navigationController?.pushViewController(vc, animated: true)
    }
    
    func tapRedPack(message: JCMessageType) {
        //MBProgressHUD_JChat.show(text: "你点击了红包", view: self.view)
        if let dict = message.jmessage?.content?.extras, let redpackId: Int = dict["redpacketId"] as? Int {
            if let msgId = message.jmessage?.serverMessageId {
                var type = MTRedpacketType.club
                if let target: JMSGGroup = conversation.target as? JMSGGroup {
                    if let desc = target.desc {
                        if !desc.contains("|.>p_t_g<.|") {
                            type = MTRedpacketType.task
                        }
                    }
                } else {
                    type = MTRedpacketType.single
                }
                MTRedpackTool.default.redpackInfo(self, redpacketId: redpackId, from:  isGroup ? 2 : 1, msgId: msgId, type: type) { [weak self] in
                    guard let weakSelf = self else { return }
                    if let index = weakSelf.messages.index(message) {
                        let msg = weakSelf._parseMessage(weakSelf.conversation.message(withMessageId: message.msgId)!, false)
                        weakSelf.messages[index] = msg
                        DispatchQueue.main.async {
                            weakSelf.chatView.update(msg, at: index)
                        }
                    }
                }
            }
        }
    }
    
    func tapTaskMessage(message: JCMessageType) {
        if let dict = message.jmessage?.content?.extras, let partyId: String = dict["partyId"] as? String, let id: Int = Int(partyId) {
            let vc = MTPartyTaskDetailViewController(partyTaskId: id)
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    func tapRedPackNotify(message: JCMessageType) {
        if let dict = message.jmessage?.content?.extras, let redpackId: Int = dict["id"] as? Int {
            if let msgId = message.jmessage?.serverMessageId {
                var type = MTRedpacketType.club
                if let target: JMSGGroup = conversation.target as? JMSGGroup {
                    if let desc = target.desc {
                        if !desc.contains("|.>p_t_g<.|") {
                            type = MTRedpacketType.task
                        }
                    }
                } else {
                    type = MTRedpacketType.single
                }
                MTRedpackTool.default.redpackInfo(self, redpacketId: redpackId, from:  isGroup ? 2 : 1, msgId: msgId, type: type) { [weak self] in
                    guard let weakSelf = self else { return }
                    if let index = weakSelf.messages.index(message) {
                        let msg = weakSelf._parseMessage(weakSelf.conversation.message(withMessageId: message.msgId)!, false)
                        weakSelf.messages[index] = msg
                        DispatchQueue.main.async {
                            weakSelf.chatView.update(msg, at: index)
                        }
                    }
                }
            }
        }
    }
    
    func tapClubActivity(message: JCMessageType) {
        if let dict = message.jmessage?.content?.extras, let activityId: Int = dict["activityId"] as? Int {
            
            let activityVC: MTClubActiviteDetailViewController = MTClubActiviteDetailViewController(group: self.conversation.target as! JMSGGroup, activityId: "\(activityId)")
            
            self.navigationController?.pushViewController(activityVC, animated: true)
            
        }
    }
    
    func tapGiftMessage(message: JCMessageType) {
        var dict: [String : Any] = [:]
        if let msgId: String = message.jmessage?.serverMessageId {
            debugPrint("tap gift Message jmessage id", msgId)
            dict.updateValue(msgId, forKey: "msgId")
        }
        dict.updateValue("pullGift", forKey: "messageType")
        if let ex: [String : Any] = message.jmessage?.content?.extras as? [String : Any] {
            if let userGiftId: Int = ex["userGiftId"] as? Int {
                provider.originRequest(.pullGift(["userGiftId" : userGiftId]), callbackQueue: .main, progress: nil) { [weak self] (result, _) in
                    guard let weakSelf = self else { return }
                    switch result {
                    case let .success(response):
                        if let datas = try? response.mapJSON() as? [String: Any], let code = datas["code"] as? Int {
                            if code == 200 {
                                dict.updateValue(1, forKey: "status")
                                weakSelf.saveLocalGiftStatus(code: code, dictData: dict, message: message, datas: datas)
                            } else if code == 800 {
                                dict.updateValue(1, forKey: "status")
                                weakSelf.saveLocalGiftStatus(code: code, dictData: dict, message: message, datas: datas)
                            } else if code == 900 {
                                dict.updateValue(2, forKey: "status")
                                weakSelf.saveLocalGiftStatus(code: code, dictData: dict, message: message, datas: datas)
                            }
                            
                            if code == 404 {
                                MBProgressHUD_JChat.show(text: "礼物领取失败", view: weakSelf.view, 1)
                            }
                        }
                        break
                        
                    case .failure(_):
                        break
                    }
                }
            }
        }
    }
    
    private func saveLocalGiftStatus(code: Int, dictData: [String : Any], message: JCMessageType, datas: [String: Any]) {
//        if let result = datas["result"] as? [String: Any] {
//            UserCenter.default.set(with: result)
//        }
        /// 礼物只涉及两个人的逻辑, 所以可以直接更改远端自定义消息的状态?
        if let index = self.messages.index(message) {
            if let status: Int = dictData["status"] as? Int {
                message.jmessage?.updateExtraValue(status, forKey: "status")
            }
            let msg = self._parseMessage(self.conversation.message(withMessageId: message.msgId)!, false)
            self.messages[index] = msg
            if code == 200 {
                DispatchQueue.main.async {
                    self.chatView.update(msg, at: index)
                    MBProgressHUD_JChat.show(text: "礼物领取成功", view: self.view, 1)
                }
            } else if code == 800 {
                DispatchQueue.main.async {
                    self.chatView.update(msg, at: index)
                    MBProgressHUD_JChat.show(text: "礼物已被领取", view: self.view, 1)
                }
            } else if code == 900 {
                DispatchQueue.main.async {
                    self.chatView.update(msg, at: index)
                    MBProgressHUD_JChat.show(text: "礼物已过期", view: self.view, 1)
                }
            }
            if let serverMsgId = message.jmessage?.serverMessageId {
                let giftInfo: MTGiftInfo = MTGiftInfo.create(msgId: serverMsgId, status: MTGiftInfoStatus(rawValue: code == 200 ? 1 : code == 800 ? 1 : 2)!)
                MTGiftInfoDB.shareInstance.insertData(giftInfo)
                
                /// 找到对应id的礼物消息刷新
                if self.messages.contains(where: { (m) -> Bool in
                    return m.jmessage?.serverMessageId == serverMsgId
                }) {
                    let indexs = chatView.indexPathsForVisibleItems
                    for index in indexs {
                        var m = messages[index.row]
                        if !m.msgId.isEmpty {
                            m = _parseMessage(conversation.message(withMessageId: m.msgId)!, false)
                            chatView.update(m, at: index.row)
                        }
                    }
                }
            }
            
            /// 通知对方
            nofityOtherUserGiftStatus(dictData: dictData)
        }
//        self.conversation.sendTransparentMessage(self.getJSONStringFromDictionary(dictionary: dictData)) { (result, error) in
//            if error == nil {
//
//            }
//        }
    }
    
    private func nofityOtherUserGiftStatus(dictData: [String : Any]) {
        let content: JMSGCustomContent = JMSGCustomContent.init(customDictionary: dictData)
        let msg: JMSGMessage = conversation.createMessage(with: content)!
        msg.updateExtraValue("pullGift", forKey: "messageType")
        if let msgId: String = dictData["msgId"] as? String {
            msg.updateExtraValue(msgId, forKey: "msgId")
        }
        if let status: Int = dictData["status"] as? Int {
            msg.updateExtraValue(status, forKey: "status")
        }
        
        let optional: JMSGOptionalContent = JMSGOptionalContent()
        let customNotification: JMSGCustomNotification = JMSGCustomNotification()
        customNotification.enabled = true
        customNotification.alert = ""
        optional.customNotification = customNotification
        //optional.noSaveNotification = false
        
        conversation.send(msg, optionalContent: optional)
//        conversation.send(msg)
    }
    
    func sendGift() {
        self.toolbar.isHidden = true
        /// 极光用户名
        let user = conversation.target as! JMSGUser
        
        self.presentGiftView(isFriend: user.isFriend, imUserName: user.username, didClickRechargeCallBack: { [weak self] in
            guard let weakself = self else { return }
            if UserDefaults.AppValidate.isValidate.storedBool == false {
                let c = MTPaymentViewController()
                weakself.navigationController?.pushViewController(c, animated: true)
            } else {
                let c = MTInAppPurchasesViewController()
                weakself.navigationController?.pushViewController(c, animated: true)
            }
            }, selectedGiftCallBack: { [weak self] (model, count) in
        }, didClickSayHiCallBack: { (model, count) in
            
        }) {
            DispatchQueue.main.async {
                self.toolbar.isHidden = false
            }
        }
    }
    
    func getJSONStringFromDictionary(dictionary: [String : Any]) -> String {
        if (!JSONSerialization.isValidJSONObject(dictionary)) {
           debugPrint("无法解析出JSONString")
           return ""
        }
        if let data : NSData = try? JSONSerialization.data(withJSONObject: dictionary, options: []) as NSData? {
            let JSONString = NSString(data: data as Data,encoding: String.Encoding.utf8.rawValue)
            return JSONString! as String
        }
        return ""
    }
}

extension JCChatViewController: JCChatViewDelegate {
    func refershChatView( chatView: JCChatView) {
        messagePage += 1
        _loadMessage(messagePage)
        chatView.stopRefresh()
    }
    
    func deleteMessage(message: JCMessageType) {
        conversation.deleteMessage(withMessageId: message.msgId)
        if let index = messages.index(message) {
            jMessageCount -= 1
            messages.remove(at: index)
            if let message = messages.last {
                if message.content is JCMessageTimeLineContent {
                    messages.removeLast()
                    chatView.remove(at: messages.count)
                }
            }
        }
    }
    
    func forwardMessage(message: JCMessageType) {
        if let message = conversation.message(withMessageId: message.msgId) {
            let vc = JCForwardViewController()
            vc.message = message
            let nav = BaseNavController(rootViewController: vc)
            nav.modalPresentationStyle = .fullScreen
            self.present(nav, animated: true, completion: {
                self.toolbar.isHidden = true
            })
        }
    }
    
    func withdrawMessage(message: JCMessageType) {
        guard let message = conversation.message(withMessageId: message.msgId) else {
            return
        }
        JMSGMessage.retractMessage(message, completionHandler: { (result, error) in
            if error == nil {
                if let index = self.messages.index(message) {
                    let msg = self._parseMessage(self.conversation.message(withMessageId: message.msgId)!, false)
                    self.messages[index] = msg
                    self.chatView.update(msg, at: index)
                }
            } else {
                MBProgressHUD_JChat.show(text: "发送时间过长，不能撤回", view: self.view)
            }
        })
    }

    func indexPathsForVisibleItems(chatView: JCChatView, items: [IndexPath]) {
        for item in items {
            if item.row <= minIndex {
                var msgs: [JCMessage] = []
                for index in item.row...minIndex  {
                    msgs.append(messages[index])
                }
                updateUnread(msgs)
                minIndex = item.row
            }
        }
    }

    fileprivate func updateUnread(_ messages: [JCMessage]) {
        for message in messages {
            if message.options.alignment != .left {
                continue
            }
            if let msg = conversation.message(withMessageId: message.msgId) {
                if msg.isHaveRead {
                    continue
                }
                msg.setMessageHaveRead({ _,_  in
                })
            }
        }
    }
}

extension JCChatViewController: UIAlertViewDelegate {

    func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) {
        if alertView.tag == 10001 {
            if buttonIndex == 1 {
                JCAppManager.openAppSetter()
            }
            return
        }
        switch buttonIndex {
        case 1:
            if let index = messages.index(currentMessage) {
                messages.remove(at: index)
                chatView.remove(at: index)
                let msg = conversation.message(withMessageId: currentMessage.msgId)
                currentMessage.options.state = .sending

                if let msg = msg {
                    if let content = currentMessage.content as? JCMessageImageContent,
                        let imageContent = msg.content as? JMSGImageContent
                    {
                        imageContent.uploadHandler = {  (percent:Float, msgId:(String?)) -> Void in
                            content.upload?(percent)
                        }
                    }
                }
                messages.append(currentMessage as! JCMessage)
                chatView.append(currentMessage)
                conversation.send(msg!, optionalContent: JMSGOptionalContent.ex.default)
                chatView.scrollToLast(animated: true)
            }
        default:
            break
        }
    }
}

extension JCChatViewController: AAPhotoBrowserProtocol {
    
    func numberOfPhotos(with browser: AAPhotoBrowser) -> Int {
        return imageMessages.count
    }
    
    func photo(of index: Int, with browser: AAPhotoBrowser) -> AAPhoto {
        
        let jmsg = imageMessages[index]
        
        let photo = AAPhoto(jmessage: jmsg, originalView: nil)
//        let photo = AAPhoto.init(urlString: String, placeholderImage: UIImage?, originalView: UIImageView?)
        return photo
        
    }
}

// MARK: - SAIInputBarDelegate & SAIInputBarDisplayable
extension JCChatViewController: SAIInputBarDelegate, SAIInputBarDisplayable {
    
    open override var inputAccessoryView: UIView? {
        return toolbar
    }
    open var scrollView: SAIInputBarScrollViewType {
        return chatView
    }
    open override var canBecomeFirstResponder: Bool {
        return true
    }
    
    open func inputView(with item: SAIInputItem) -> UIView? {
        if let view = inputViews[item.identifier] {
            return view
        }
        switch item.identifier {
        case "kb:emoticon":
            let view = JCEmoticonInputView()
            view.delegate = self
            view.dataSource = self
            inputViews[item.identifier] = view
            return view
        case "kb:toolbox":
            let view = SAIToolboxInputView()
            view.delegate = self
            view.dataSource = self
            inputViews[item.identifier] = view
            return view
        default:
            return nil
        }
    }
    
    open func inputViewContentSize(_ inputView: UIView) -> CGSize {
        return CGSize(width: view.frame.width, height: 216)
    }
    
    func inputBar(_ inputBar: SAIInputBar, shouldDeselectFor item: SAIInputItem) -> Bool {
        return true
    }
    open func inputBar(_ inputBar: SAIInputBar, shouldSelectFor item: SAIInputItem) -> Bool {
        if item.identifier == "kb:audio" {
            return true
        } else if item.identifier == "kb:emoticon" {
            if toolbar.hasUserInputText() == false {
                toolbar.setInputViewText("")
            }
            return true
        } else if item.identifier == "kb:toolbox" {
            if toolbar.hasUserInputText() == false {
                toolbar.setInputViewText(AppPlaceholder.inputViewPlaceholder)
            }
            return true
        }
        guard let _ = inputView(with: item) else {
            return false
        }
        return true
    }
    open func inputBar(_ inputBar: SAIInputBar, didSelectFor item: SAIInputItem) {
        inputItem = item
        
        if item.identifier == "kb:audio" {
            inputBar.deselectBarAllItem()
            return
        } else if item.identifier == "kb:emoticon" {
            if toolbar.hasUserInputText() == false {
                toolbar.setInputViewText("")
            }
        }
        if let kb = inputView(with: item) {
            inputBar.setInputMode(.selecting(kb), animated: true)
        }
    }
    open func inputBar(didChangeMode inputBar: SAIInputBar) {
        if inputItem?.identifier == "kb:audio" {
            return
        } else if inputItem?.identifier == "kb:emoticon" {
            if toolbar.hasUserInputText() == false {
                toolbar.setInputViewText("")
            }
        }
        if let item = inputItem, !inputBar.inputMode.isSelecting {
            inputBar.deselectBarItem(item, animated: true)
        }
    }
    
    open func inputBar(didChangeText inputBar: SAIInputBar) {
        _emoticonSendBtn.isEnabled = inputBar.attributedText.length != 0
    }
    
    public func inputBar(shouldReturn inputBar: SAIInputBar) -> Bool {
        if inputBar.attributedText.length == 0 {
            return false
        }
        send(forText: inputBar.attributedText)
        inputBar.attributedText = nil
        return false
    }
    
    func inputBar(_ inputBar: SAIInputBar, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let currentIndex = range.location
        if !isGroup {
            return true
        }
        if string == "@" {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
                let vc = JCRemindListViewController()
                vc.finish = { (user, isAtAll, length) in
                    self.handleAt(inputBar, range, user, isAtAll, length)
                }
                vc.group = self.conversation.target as! JMSGGroup
                let nav = BaseNavController(rootViewController: vc)
                nav.modalPresentationStyle = .fullScreen
                self.present(nav, animated: true, completion: {})
            }
        } else {
            return updateRemids(inputBar, string, range, currentIndex)
        }
        return true
    }

    func handleAt(_ inputBar: SAIInputBar, _ range: NSRange, _ user: JMSGUser?, _ isAtAll: Bool, _ length: Int) {
        let text = inputBar.text!
        let currentIndex = range.location
        var displayName = "所有成员"

        if let user = user {
            displayName = user.displayName()
        }
        let remind = JCRemind(user, currentIndex, currentIndex + 2 + displayName.length, displayName.length + 2, isAtAll)
        if text.length == currentIndex + 1 {
            inputBar.text = text + displayName + " "
        } else {
            let index1 = text.index(text.endIndex, offsetBy: currentIndex - text.length + 1)
            let prefix = text.substring(with: (text.startIndex..<index1))
            let index2 = text.index(text.startIndex, offsetBy: currentIndex + 1)
            let suffix = text.substring(with: (index2..<text.endIndex))
            inputBar.text = prefix + displayName + " " + suffix
            let _ = self.updateRemids(inputBar, "@" + displayName + " ", range, currentIndex)
        }
        self.reminds.append(remind)
        self.reminds.sort(by: { (r1, r2) -> Bool in
            return r1.startIndex < r2.startIndex
        })
    }
    
    func updateRemids(_ inputBar: SAIInputBar, _ string: String, _ range: NSRange, _ currentIndex: Int) -> Bool {
        for index in 0..<reminds.count {
            let remind = reminds[index]
            let length = remind.length
            let startIndex = remind.startIndex
            let endIndex = remind.endIndex
            // Delete
            if currentIndex == endIndex - 1 && string.length == 0 {
                for _ in 0..<length {
                    inputBar.deleteBackward()
                }
                // Move Other Index
                for subIndex in (index + 1)..<reminds.count {
                    let subTemp = reminds[subIndex]
                    subTemp.startIndex -= length
                    subTemp.endIndex -= length
                }
                reminds.remove(at: index)
                return false;
            } else if currentIndex > startIndex && currentIndex < endIndex {
                // Delete Content
                if string.length == 0 {
                    for subIndex in (index + 1)..<reminds.count {
                        let subTemp = reminds[subIndex]
                        subTemp.startIndex -= 1
                        subTemp.endIndex -= 1
                    }
                    reminds.remove(at: index)
                    return true
                }
                // Add Content
                else {
                    for subIndex in (index + 1)..<reminds.count {
                        let subTemp = reminds[subIndex]
                        subTemp.startIndex += string.length
                        subTemp.endIndex += string.length
                    }
                    reminds.remove(at: index)
                    return true
                }
            }
        }
        for index in 0..<reminds.count {
            let tempDic = reminds[index]
            let startIndex = tempDic.startIndex
            if currentIndex <= startIndex {
                if string.count == 0 {
                    for subIndex in index..<reminds.count {
                        let subTemp = reminds[subIndex]
                        subTemp.startIndex -= 1
                        subTemp.endIndex -= 1
                    }
                    return true
                } else {
                    for subIndex in index..<reminds.count {
                        let subTemp = reminds[subIndex]
                        subTemp.startIndex += string.length
                        subTemp.endIndex += string.length
                    }
                    return true
                }
            }
        }
        return true
    }
    
    func inputBar(touchDown recordButton: UIButton, inputBar: SAIInputBar) {
        if recordingHub != nil {
            recordingHub.removeFromSuperview()
        }
        recordingHub = JCRecordingView(frame: CGRect.zero)
        recordHelper.updateMeterDelegate = recordingHub
        recordingHub.startRecordingHUDAtView(view)
        recordingHub.frame = CGRect(x: view.centerX - 70, y: view.centerY - 70, width: 136, height: 136)
        recordHelper.startRecordingWithPath(String.getRecorderPath()) {
        }
    }
    
    func inputBar(dragInside recordButton: UIButton, inputBar: SAIInputBar) {
        recordingHub.pauseRecord()
    }
    
    func inputBar(dragOutside recordButton: UIButton, inputBar: SAIInputBar) {
        recordingHub.resaueRecord()
    }
    
    func inputBar(touchUpInside recordButton: UIButton, inputBar: SAIInputBar) {
        if recordHelper.recorder ==  nil {
            return
        }
        recordHelper.finishRecordingCompletion()
        if (recordHelper.recordDuration! as NSString).floatValue < 1 {
            recordingHub.showErrorTips()
            let time: TimeInterval = 1.5
            let hub = recordingHub
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time) {
                hub?.removeFromSuperview()
            }
            return
        } else {
            recordingHub.removeFromSuperview()
        }
        let data = try! Data(contentsOf: URL(fileURLWithPath: recordHelper.recordPath!))
        send(voiceData: data, duration: Double(recordHelper.recordDuration!)!)
    }
    
    func inputBar(touchUpOutside recordButton: UIButton, inputBar: SAIInputBar) {
        recordHelper.cancelledDeleteWithCompletion()
        recordingHub.removeFromSuperview()
    }
}

// MARK: - JCRecordVoiceHelperDelegate
extension JCChatViewController: JCRecordVoiceHelperDelegate {
    public func beyondLimit(_ time: TimeInterval) {
        recordHelper.finishRecordingCompletion()
        recordingHub.removeFromSuperview()
        let data = try! Data(contentsOf: URL(fileURLWithPath: recordHelper.recordPath!))
        send(voiceData: data, duration: Double(recordHelper.recordDuration!)!)
    }
}

extension JCChatViewController: UIGestureRecognizerDelegate {
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        guard let view = touch.view else {
            return true
        }
        if view.isKind(of: JCMessageTextContentView.self) {
            return false
        }
        return true
    }
}

extension JCChatViewController: UIDocumentInteractionControllerDelegate {
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self
    }
    func documentInteractionControllerViewForPreview(_ controller: UIDocumentInteractionController) -> UIView? {
        return view
    }
    func documentInteractionControllerRectForPreview(_ controller: UIDocumentInteractionController) -> CGRect {
        return view.frame
    }
}

// MARK: - MTChatSendGiftVewDelegate
//extension JCChatViewController: MTChatSendGiftVewDelegate {
//    func didSelectedSendGift(_ giftView: MTChatSendGiftVew) {
//        let viewHeight = giftView.height
//    }
//
//    func didSelectedaddFriend(_ giftView: MTChatSendGiftVew, user: JMSGUser) {
//        let vc = MTAddFriendViewController()
//        vc.userName = user.username
//        self.navigationController?.pushViewController(vc, animated: true)
//    }
//}


// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromUIImagePickerControllerInfoKeyDictionary(_ input: [UIImagePickerController.InfoKey: Any]) -> [String: Any] {
	return Dictionary(uniqueKeysWithValues: input.map {key, value in (key.rawValue, value)})
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromUIImagePickerControllerInfoKey(_ input: UIImagePickerController.InfoKey) -> String {
	return input.rawValue
}


extension  JCChatViewController {
    override func yp_navigtionBarConfiguration() -> YPNavigationBarConfigurations {
        return [.backgroundStyleColor, .backgroundStyleOpaque, .showShadowImage]
    }
}
